package usecase;

import IBO.IClient;
import IBO.ICodePostal;
import IBO.IIntervention;
import IGUI.Subscriber;
import IUSECASE.IUC_Factory;
import IUSECASE.IUC_GestionIntervention;
import bo.Adresse;
import bo.Client;
import bo.CodePostal;
import bo.Intervention;
import bo.ListeInterventions;
import boerrors.AdresseInexistantException;
import boerrors.AdresseMinimumMultiplicityException;
import boerrors.CodePostalInexistantException;
import boerrors.CodePostalMinimumMultiplicityException;
import boerrors.InterventionInexistantException;
import boerrors.ZoneMinimumMultiplicityException;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.GregorianCalendar;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
 
public class GestionInterventions extends UnicastRemoteObject implements IUC_GestionIntervention, Serializable {

        private static GestionInterventions instance = null;    
   
        //*******************************************************************    
        //Constructeur du singleton    
        //*******************************************************************        
        public static GestionInterventions getInstance() throws RemoteException {        
                if(instance == null) instance = new GestionInterventions();        
                return instance;    
        }
   
        public GestionInterventions() throws RemoteException {
                super();
        } 
   
        private Vector<IIntervention> convertLstIntToLstIInt(Vector<Intervention> liste) {
                Vector<IIntervention> listeTampon = new Vector<IIntervention>();
                for (int i = 0; i < liste.size(); i++) listeTampon.add((IIntervention)liste.get(i));
                return listeTampon;
        }
   
        //*******************************************************************
        //Convertir objet BO en objet IBO
        //*******************************************************************
        
        //Code Postal
        private Vector<ICodePostal> convertCPtoICP(Vector<CodePostal> listeCP) {
                Vector<ICodePostal> lstTmp = new Vector<ICodePostal>();
                for (int i = 0; i < listeCP.size(); i++){lstTmp.add((ICodePostal) listeCP.get(i));}
                return lstTmp;
        }
        
        //*******************************************************************    
        //Methodes heritees    
        //******************************************************************* 
 
        //Gestion des Interventions
        public IIntervention creerIntervention( IClient client, String degre, String description, String rue, 
                                                String numero, String[] codePostal, GregorianCalendar dateDemande) 
                                                throws RemoteException {
                try {
                    CodePostal cp = CodePostal.rechercherCodePostal(codePostal[1], codePostal[2]);
                    Adresse adresse = new Adresse(rue, numero, cp);
                    //Client clt = ListeClients.getInstance().rechercherParticulierIdClient(client.getIdClient());
                    Client clt = bo.ListeClients.getInstance().rechercherIdClient(client.getIdClient());
                    return new Intervention(clt, adresse, description, degre, dateDemande);
                } catch (CodePostalInexistantException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
        }
    
       public IIntervention creerIntervention( IClient client, String degre, String description
                                                , String[] adresse, GregorianCalendar dateDemande) 
                                                throws RemoteException {
                try {
                    CodePostal cp = CodePostal.rechercherCodePostal(adresse[3], adresse[4]);
                    
                    Adresse adr = new Adresse(Integer.parseInt(adresse[0]), adresse[1], adresse[2], cp);
                    //Integer.parseInt(adresse[0])
                    //Client clt = ListeClients.getInstance().rechercherParticulierIdClient(client.getIdClient());
                    Client clt = bo.ListeClients.getInstance().rechercherIdClient(client.getIdClient());
                    return new Intervention(clt, adr, description, degre, dateDemande);
                } catch (CodePostalInexistantException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
        }
    
        
        public void modifierIntervention(   int idIntervention, String prioriteDemande, 
                                            String descriptionDemande, String rue, String numero, 
                                            String commune, String codePostal) throws RemoteException {
                try {
                    //On recupere l'intervention en fonction de son numero d'intervention
                    Intervention intervention = bo.ListeInterventions.getInstance().rechercherIntervention(idIntervention);
                    Intervention clone = (Intervention) intervention.clone();
                    //Echo pour verifier que les references sont bien differentes
                    System.out.println(intervention.hashCode());
                    System.out.println(clone.hashCode());
                    //On definit les attributs du clone
                    clone.setPrioriteDemande(prioriteDemande);
                    clone.setDescriptionDemande(descriptionDemande);
                    clone.getAdresse().setIdAdresse(intervention.getAdresse().getIdAdresse());
                    clone.getAdresse().setRue(rue);
                    clone.getAdresse().setNumero(numero);
                    clone.getAdresse().enregistrerCodePostal(CodePostal.rechercherCodePostal(codePostal, commune));
                    //On insere les valeurs du clone dans la DB
                    bo.Intervention.modifier(clone);
                    //L'insertion c'est passee correctement
                    //On reassigne les valeurs du clone à l'intervention.
                    intervention.setPrioriteDemande(clone.getPrioriteDemande());
                    intervention.setDescriptionDemande(clone.getDescriptionDemande());
                    intervention.getAdresse().setIdAdresse(clone.getAdresse().getIdAdresse());
                    intervention.getAdresse().setRue(clone.getAdresse().getRue());
                    intervention.getAdresse().setNumero(clone.getAdresse().getNumero());
                    intervention.getAdresse().enregistrerCodePostal(clone.getAdresse().getCodePostal());
                    //Modification terminee
                } catch (CloneNotSupportedException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                } catch (CodePostalInexistantException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InterventionInexistantException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                } catch (AdresseInexistantException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                } catch (CodePostalMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                } catch (ZoneMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                }
        }
                
        public Vector<IIntervention> listeInterventions() throws RemoteException {
                
            Vector<IIntervention> listeTmp = convertLstIntToLstIInt(bo.ListeInterventions.getInstance().getListeIntervention());
            return listeTmp;
        }

        public Vector<IIntervention> listeInterventionAReplanifier() throws RemoteException{
                Vector<IIntervention> listeTampon = convertLstIntToLstIInt(bo.ListeInterventions.getInstance().listeInterventionDeplanifiee());
                return listeTampon;
        }    
    
        public Vector<IIntervention> listeInterventionAPlanifier() throws RemoteException{
                Vector<IIntervention> listeTampon = convertLstIntToLstIInt(bo.ListeInterventions.getInstance().listeInterventionAPlanifier());
                return listeTampon;
        }
        
        public Vector<IIntervention> rechercherIntervention(int numeroIntervention) throws RemoteException{
                Vector<IIntervention> lstIntervention = new Vector<IIntervention>();
                Intervention intTmp = bo.ListeInterventions.getInstance().rechercherIntervention(numeroIntervention);
                if (intTmp != null)
                    lstIntervention.add(intTmp);
                return lstIntervention;
        }
    
        public Vector<IIntervention> rechercherListeOuvertes(int numeroClient) throws RemoteException{
                Client client = bo.ListeClients.getInstance().rechercherIdClient(numeroClient);
                return client.getListeInterventions();
        }
        
        public Vector<IIntervention> rechercherListeCloturees(int numeroClient) throws RemoteException{
                try {
                    Client client = bo.ListeClients.getInstance().rechercherIdClient(numeroClient);
                    return convertLstIntToLstIInt(bo.Intervention.rechercher((Client) client));
                } catch (InterventionInexistantException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                } catch (AdresseMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                } catch (CodePostalMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                } catch (ZoneMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
        }
                
        public Vector<IIntervention> rechercherListeComplete(int numeroClient) throws RemoteException{
                try {
                    Vector<IIntervention> listeComplete = null;
                    Vector<IIntervention> listeOuvertes = null;
                    Client client = bo.ListeClients.getInstance().rechercherIdClient(numeroClient);
                    listeOuvertes = client.getListeInterventions();
                    listeComplete = convertLstIntToLstIInt(bo.Intervention.rechercher((Client) client));
                    for (int i = 0; i < listeOuvertes.size(); i++) {
                        listeComplete.add(listeOuvertes.get(i));
                    }
                    return listeComplete;
                } catch (InterventionInexistantException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                } catch (AdresseMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                } catch (CodePostalMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                } catch (ZoneMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
        }
            
        public Vector<ICodePostal> rechercherCP(String codePostal) throws RemoteException {
                try {
                    return convertCPtoICP(bo.CodePostal.listerCodePostaux(codePostal));
                } catch (Exception ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                    }
        }

        public Vector<ICodePostal> rechercherCommune(String commune) throws RemoteException {
                try {
                    return convertCPtoICP(bo.CodePostal.listerCodePostaux(commune));
                } catch (Exception ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                    return null;
                }
        }
 
        public void annuler(IIntervention intervention) 
                            throws RemoteException {
                try {
                    Intervention interventionTampon = ListeInterventions.getInstance().rechercherIntervention(intervention.getIdIntervention());
                    interventionTampon.annuler();
                } catch (InterventionInexistantException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                } catch (AdresseInexistantException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                } catch (CodePostalMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                } catch (ZoneMinimumMultiplicityException ex) {
                    Logger.getLogger(GestionInterventions.class.getName()).log(Level.SEVERE, null, ex);
                }
        }

        //*******************************************************************    
        //MVC    
        //*******************************************************************        
        
        public void subscribingListeInterventions(Subscriber subscriber) throws RemoteException{
            ListeInterventions.getInstance().subscribe(subscriber);
        }
        
        public void unSubscribingListeInterventions(Subscriber subscriber) throws RemoteException{
            ListeInterventions.getInstance().unsubscribe(subscriber);
        }    
        
        
}